﻿using Culvert_Help;
using NeXus.BIMBase;
using NeXus.BIMBase.Core;
using NeXus.p3d;
using NeXus.PBBim.PBBimCore;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;

namespace checc_baseTools
{
    public class DynamicLibrary
    {
        /// <summary>
        /// 修改线性颜色
        /// </summary>
        /// <param name="lineString">线元素</param>
        /// <param name="color">颜色</param>
        /// <param name="weight">线宽</param>
        /// <param name="style">线型</param>
        /// <returns></returns>
        public static void ModifiedLinearColor(ref BPGraphics graphic, IGeCurveBase lineString, Color color = default, uint weight = default, int style = default, double transparency = default)
        {
            var argb = BPColorUtil.getEntityColor(new BPColorDef(color.R, color.G, color.B), GeneralHelpers.bPProject, true);
            //颜色，线宽，线型赋值
            BPSymbology symbology = new BPSymbology
            {
                color = argb,
                weight = weight,
                style = style
            };
            graphic.addGeCurve(lineString, symbology, transparency);
        }

        /// <summary>
        /// 点集合创建线
        /// </summary>
        /// <param name="points">点集合</param>
        /// <param name="color">颜色</param>
        /// <param name="weight">线宽</param>
        /// <param name="style">线型</param> 
        /// <returns>基本曲线</returns>
        public static BPGraphics Line(GePoint3dCollection points, BPModel bPModel, Color color = default, uint weight = default, int style = default)
        {
            BPGraphics graphic = bPModel.createPhysicalGraphics();
            //创建线
            var lineString = IGeCurveBase.createLineString(points);
            var argb = BPColorUtil.getEntityColor(new BPColorDef(color.R, color.G, color.B), GeneralHelpers.bPProject, true);
            //颜色，线宽，线型赋值
            BPSymbology symbology = new BPSymbology
            {
                color = argb,
                weight = weight,
                style = style
            };
            graphic.addGeCurve(lineString, symbology);
            //graphic.save();

            return graphic;
        }

        /// <summary>
        /// 创建复杂链元素
        /// </summary>
        /// <param name="curveList">链类元素集合</param>
        /// <param name="color">颜色</param>
        /// <param name="weight">线宽</param>
        /// <param name="style">线型</param>
        /// <returns>基本曲线</returns>
        public static IGeCurveBase Chains(GeCurveArray curveList, Color color = default, uint weight = default, int style = default)
        {
            //创建线
            var complexChain = IGeCurveBase.createChildCurveArray(curveList);
            var argb = BPColorUtil.getEntityColor(new BPColorDef(color.R, color.G, color.B), GeneralHelpers.bPProject, true);
            //颜色，线宽，线型赋值
            BPSymbology symbology = new BPSymbology
            {
                color = argb,
                weight = weight,
                style = style
            };
            BPGraphics bPGraphicsPtr = BPApplication.getInstance().getProjectManager().getActiveModel().createPhysicalGraphics();
            bPGraphicsPtr.addGeCurve(complexChain, symbology, 0);
            bPGraphicsPtr.save();

            return complexChain;
        }

        /// <summary>
        /// 起点，圆心，终点创建弧
        /// </summary>
        /// <param name="startPoint">起点</param>
        /// <param name="center">圆心</param>
        /// <param name="endTarget">终点</param>
        /// <returns>基本曲线</returns>
        public static IGeCurveBase Arc(GePoint3d startPoint, GePoint3d center, GePoint3d endTarget)
        {
            //创建弧
            var arc = IGeCurveBase.createEllipse(GeEllipse3d.createByEllipseCenterStartEnd(center, startPoint, endTarget));
            BPGraphics bPGraphicsPtr = BPApplication.getInstance().getProjectManager().getActiveModel().createPhysicalGraphics();
            bPGraphicsPtr.addGeCurve(arc);
            bPGraphicsPtr.save();

            return arc;
        }

        ///// <summary>
        ///// 起点，终点，弧长创建弧
        ///// </summary>
        ///// <param name="startPoint">起点</param>
        ///// <param name="endTarget">终点</param>
        ///// <param name="length">弧长</param>
        ///// <returns></returns>
        //public static void Arc(GePoint3d startPoint, GePoint3d endTarget, double length)
        //{
        //    /***********************************没有弧长的接口**************************************/
        //    //BPDocument doc = BPApplication.singleton().activeDocument;
        //    //BPModel model = doc.modelManager.activeModel;
        //    //BPModelArc arc = new BPModelArc();
        //    //return arc;
        //}

        ///// <summary>
        ///// 根据线上距离计算线上得一点
        ///// </summary>
        ///// <param name="curves">线元素集合</param>
        ///// <param name="length">距离</param>
        ///// <returns></returns>
        //public static GePoint3d GetLineLengthDpoint(List<IGeCurveBase> curves, double length)
        //{
        //    BPTrafficCurveComposite curveComposite = new BPTrafficCurveComposite();
        //    curveComposite = BPTrafficPlaneCurveComposite.create();
        //    double sumLength = 0;
        //    foreach (IGeCurveBase curve in curves)
        //    {
        //        sumLength += curve.length;
        //        curveComposite.append(curve.clone());
        //    }

        //    if (Math.Round(length, 3) == Math.Round(sumLength, 3))
        //        return curves[curves.Count - 1].endPoint;

        //    BPTrafficPlaneCurveComposite curvePComposite = curveComposite as BPTrafficPlaneCurveComposite;
        //    GePoint3d point = GePoint3d.createByZero();
        //    curvePComposite.getPointFromLength(length, ref point);
        //    return point;
        //}

        ///// <summary>
        ///// 创建文字属性
        ///// </summary>
        ///// <param name="strFont">字体</param>
        ///// <param name="strBigFont">大字体</param>
        ///// <param name="extent">字体大小</param>
        ///// <param name="model">指定的模型空间 </param>
        ///// <returns>文字属性</returns>
        //public static BPTextProperties TextProperties(string strFont, string strBigFont, GePoint2d extent, BPModel model)
        //{
        //    BPTextProperties pro = BPTextProperties.create(strFont, strBigFont, extent, model);

        //    return pro;
        //}

        /// <summary>
        /// 创建文本元素
        /// </summary>
        /// <param name="content">内容</param>
        /// <param name="Slope_subgrade">文字左下角的坐标</param>
        /// <param name="rotMatrix">文字的旋转变换矩阵</param>
        /// <param name="textProperty">文字的属性</param>
        /// <param name="color">颜色</param>
        /// <returns>文字对象</returns>
        public static BPText DrawingText(string content, GePoint3d Slope_subgrade, GeRotMatrix rotMatrix, BPTextProperties textProperty, Color color = default)
        {
            BPGraphics bPGraphicsPtr = BPApplication.getInstance().getProjectManager().getActiveModel().createPhysicalGraphics();
            BPSymbology symbology = new BPSymbology();
            var text = BPText.create(content, Slope_subgrade, rotMatrix, textProperty);
            symbology.color = (uint)color.ToArgb();
            bPGraphicsPtr.addText(text, symbology, 0);
            bPGraphicsPtr.save();
            return text;
        }

        /// <summary>
        /// 新建图层
        /// </summary>
        /// <param name="layerName">图层名字</param>
        /// <param name="m_color">图层颜色</param>
        /// <param name="m_lineWeight">图层线宽</param>
        /// <param name="m_style">图层线型</param>
        public static BPLayerInfo CreateLayers(string layerName, uint m_color, int m_lineWeight, int m_style)
        {
            BPProject project = BPApplication.getInstance().getProjectManager().getMainProject();

            PLayerId layerId = new PLayerId();
            P3DStatus status = BPLayerUtil.getLayerIdByName(layerId, project, layerName);
            //颜色，线宽，线型赋值
            BPLayerInfo info = new BPLayerInfo();
            info.m_name = layerName;
            info.m_color = m_color;
            info.m_lineWeight = (uint)m_lineWeight;
            info.m_style = m_style;

            if (status == P3DStatus.ERROR)//说明要新建一个这个图层
            {
                BPLayerUtil.createLayer(layerId, project, info);
                MessageBox.Show("创建图层成功");
                return info;
            }
            else
            {
                MessageBox.Show("已经有该图层");
                //
                return info;
            }
        }


        /// <summary>
        /// 删除图层
        /// </summary>
        /// <param name="layerName">图层名字</param>
        public static void DeleteLayers(string layerName)
        {
            BPProject project = BPApplication.getInstance().getProjectManager().getMainProject();

            PLayerId layerId = new PLayerId();
            P3DStatus status = BPLayerUtil.getLayerIdByName(layerId, project, layerName);
            BPLayerInfo info = new BPLayerInfo();
            info.m_name = layerName;

            if (status != P3DStatus.ERROR)
            {
                BPLayerUtil.deleteLayer(project, info);
                MessageBox.Show("删除图层完成");
            }
            else
            {
                MessageBox.Show("没有此图层");
            }

        }

        ///// <summary>
        ///// 获取子元素
        ///// </summary>
        ///// <param name="bPGraphics"></param>
        ///// <returns></returns>
        //public static List<IGeCurveBase> GetBPGraphicsIGeCurveBase(BPGraphics bPGraphics)
        //{
        //    List<IGeCurveBase> IGeCurveBaseS = new List<IGeCurveBase>();
        //    for (int i = 0; i < bPGraphics.size; i++)
        //    {
        //        BPGraphics.Type type = bPGraphics.getType(i);
        //        if (type == BPGraphics.Type.GeCurveArray)
        //        {
        //            GeCurveArray geCurveArray = bPGraphics.getAsCurveVector(i);

        //            for (int k = 0; k < geCurveArray.size; k++)
        //            {
        //                IGeCurveBase geCurveBase = geCurveArray.at(k);
        //                CurveBaseType curveBaseType = geCurveBase.getCurveBaseType();
        //                if (curveBaseType == CurveBaseType.LineString)
        //                {
        //                    List<GePoint3d> gePoint3Ds = geCurveBase.getLineString();
        //                    for (int j = 0; j < gePoint3Ds.Count - 1; j++)
        //                    {
        //                        IGeCurveBaseS.Add(IGeCurveBase.createSegment(new GeSegment3d(gePoint3Ds[j], gePoint3Ds[j + 1])));
        //                    }
        //                }
        //                else
        //                {
        //                    if (geCurveBase != null)
        //                        IGeCurveBaseS.Add(geCurveBase);
        //                }
        //            }
        //        }
        //        else
        //        {
        //            IGeCurveBase geCurveBase = bPGraphics.getAsCurve(i);
        //            CurveBaseType curveBaseType = geCurveBase.getCurveBaseType();
        //            if (curveBaseType == CurveBaseType.LineString)
        //            {
        //                List<GePoint3d> gePoint3Ds = geCurveBase.getLineString();
        //                for (int j = 0; j < gePoint3Ds.Count - 1; j++)
        //                {
        //                    IGeCurveBaseS.Add(IGeCurveBase.createSegment(new GeSegment3d(gePoint3Ds[j], gePoint3Ds[j + 1])));
        //                }
        //            }
        //            else
        //            {
        //                if (geCurveBase != null)
        //                    IGeCurveBaseS.Add(geCurveBase);
        //            }
        //        }
        //    }
        //    return IGeCurveBaseS;
        //}

        ///// <summary>
        ///// 两个复杂曲线的投影交点
        ///// </summary>
        ///// <param name="curve"></param>
        ///// <param name="curveB"></param>
        ///// <returns></returns>
        //public static GePoint3d GetIntersectPoint(GeCurveArray curve1, GeCurveArray curve2)
        //{
        //    for (int k = 0; k < curve1.size; k++)
        //    {
        //        IGeCurveBase curveBaseA = curve1.at(k);
        //        GeCurveArray curveA = GeCurveArray.create(GeCurveArray.BoundaryType.Outer);
        //        curveA.add(curveBaseA);

        //        for (int l = 0; l < curve2.size; l++)
        //        {
        //            IGeCurveBase curveBaseB = curve2.at(l);
        //            GeCurveArray curveB = GeCurveArray.create(GeCurveArray.BoundaryType.Outer);
        //            curveB.add(curveBaseB);

        //            GeCurveArray intersectionA = GeCurveArray.create(GeCurveArray.BoundaryType.Outer);
        //            GeCurveArray intersectionB = GeCurveArray.create(GeCurveArray.BoundaryType.Outer);

        //            GeMatrix4d mat = GeMatrix4d.create(GeTransform.createIdentityMatrix());
        //            GeCurveFunction.calculateIntersection2D(ref intersectionA, ref intersectionB, curveA, curveB, mat);
        //            for (int i = 0; i < intersectionA.size; i++)
        //            {
        //                IGeCurveBase curveBase = intersectionA.at(i);
        //                GeProportCurveInfo proportCurveInfo = curveBase.getProportCurveInfo();
        //                double proportPara0 = proportCurveInfo.proportPara0;
        //                double proportPara1 = proportCurveInfo.proportPara1;
        //                GeProportCurveInfo infoA = null;
        //                GeProportCurveInfo infoB = null;
        //                bool result = GeCurveFunction.getProportCurveInfoPair(intersectionA, intersectionB, i, ref infoA, ref infoB);
        //                if (result == true)
        //                {
        //                    double length = infoA.proportPara0 * curveA.length;
        //                    List<IGeCurveBase> curves = new List<IGeCurveBase>();
        //                    for (int j = 0; j < curveA.size; j++)
        //                    {
        //                        curves.Add(curveA.at(j));
        //                    }
        //                    return GetLineLengthDpoint(curves, length);
        //                }
        //            }
        //        }
        //    }
        //    return GePoint3d.createByZero();
        //}

        ///// <summary>
        ///// 根据线外一点 获取路线上所有子集的最近点集合
        ///// </summary>
        ///// <param name="geCurveArrays">线的GeCurveArray类型集合</param>
        ///// <param name="point3D">线外一点</param>
        ///// <returns></returns>
        //public static List<GeCurveLocationInfo> GetAllInfos(List<GeCurveArray> geCurveArrays, GePoint3d point3D)
        //{
        //    List<GeCurveLocationInfo> pointInfo = new List<GeCurveLocationInfo>();

        //    int count = geCurveArrays.Count;
        //    for (int i = 0; i < count; i++)
        //    {
        //        GeCurveArray curveArray = geCurveArrays[i];
        //        GeCurveLocationInfo info = curveArray.getClosestPointBounded(point3D);

        //        pointInfo.Add(info);
        //    }

        //    return pointInfo;
        //}

        ///// 计算线外一点在此条路线上的最近位置
        ///// </summary>
        ///// <param name="infos"></param>
        ///// <param name="point"></param>
        ///// <returns></returns>
        //public static (GeCurveLocationInfo info, int index) GetClosetInfo(List<GeCurveLocationInfo> infos, GePoint3d point)
        //{
        //    int index = 0;
        //    if (infos == null || infos.Count == 0) return (null, index);

        //    if (infos.Count == 1) return (infos[0], index);
        //    else
        //    {
        //        GeCurveLocationInfo locationInfo = infos[0];
        //        double length = point.distanceTo(infos[0].point);
        //        for (int i = 1; i < infos.Count; i++)
        //        {
        //            double temp = point.distanceTo(infos[i].point);
        //            if (length > temp)
        //            {
        //                locationInfo = infos[i];
        //                index = i;
        //            }
        //            length = point.distanceTo(locationInfo.point);
        //        }
        //        return (locationInfo, index);
        //    }

        //}

        ///// 偏移
        ///// </summary>
        ///// <param name="geCurveBase"></param>
        ///// <param name="offset">左负右正</param>
        ///// <returns></returns>
        //public static IGeCurveBase LineOffset(List<IGeCurveBase> geCurveBase, double offset)
        //{
        //    #region 第二种偏移＋剪切
        //    //BPTrafficCurveComposite curveComposite = new BPTrafficCurveComposite();
        //    //curveComposite = BPTrafficPlaneCurveComposite.create();
        //    //double length = 0;
        //    //foreach (IGeCurveBase curve in geCurveBase)
        //    //{
        //    //    length += curve.length;
        //    //    curveComposite.append(curve);
        //    //}
        //    //BPTrafficPlaneCurveComposite curvePComposite = curveComposite as BPTrafficPlaneCurveComposite;
        //    //GeCurveOffsetOptions option = new GeCurveOffsetOptions(offset);
        //    //GeCurveArray curveArrayo = curvePComposite.cloneOffsetCurvesBetweenLength(option, 0, length);
        //    #endregion
        //    GeCurveArray geCurveArray = GeCurveArray.create(GeCurveArray.BoundaryType.None);
        //    foreach (IGeCurveBase item in geCurveBase)
        //    {
        //        geCurveArray.add(item.clone());
        //    }
        //    GeCurveOffsetOptions option = new GeCurveOffsetOptions(offset);
        //    GeCurveArray newarray = geCurveArray.cloneOffsetCurves2D(option);
        //    if (newarray.size == 1)
        //    {
        //        IGeCurveBase geCurveBase1 = newarray.at(0);
        //        return geCurveBase1;
        //    }

        //    IGeCurveBase complexChain = IGeCurveBase.createChildCurveArray(newarray);
        //    return complexChain;
        //}
    }
}
